﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;

using Clipper.Model.WorkDataModel;
using Clipper.Model;
using Clipper.Model.ViewModel;
using Global;

namespace Clipper.BLL.Supplier
{
    /// <summary>
    /// 整理检测所需数据
    /// </summary>
    public class DetectionOrder
    {
        #region --------成员变量-----------

        private ObservableCollection<UserSettedDetectItem> mUserSettedDetectItemList;   // 用户设置的检查项列表
        ObservableCollection<ReactionCup> mCupList = new ObservableCollection<ReactionCup>();//反应杯列表
        ObservableCollection<ReactionStrip> mStripList = new ObservableCollection<ReactionStrip>();//反应条列表
        #endregion --------成员变量-----------

        #region // -----属性------------
        /// <summary>
        /// 用户设置的检查项列表
        /// </summary>
        public ObservableCollection<UserSettedDetectItem> UserSettedDetectItemList
        {
            get { return mUserSettedDetectItemList; }
            set { mUserSettedDetectItemList = value; }
        }
        /// <summary>
        /// 反应条列表
        /// </summary>
        public ObservableCollection<ReactionStrip> StripList
        {
            get { return mStripList; }
            set
            {
                mStripList = value;
            }
        }
        /// <summary>
        /// 反应杯列表
        /// </summary>
        public ObservableCollection<ReactionCup> CupList
        {
            get { return mCupList; }
            set { mCupList = value; }
        }
        #endregion // -----属性------------

        #region // 构造函数
        /// <summary>
        /// 构造函数
        /// </summary>
        public DetectionOrder()
        {
        }
        #endregion // 构造函数        

        #region // 根据用户设置，生成反应杯列表
        /// <summary>
        /// 根据用户设置，生成检查项列表
        /// </summary>
        public ObservableCollection<ReactionCup> GenerateCupList(WorkSheetVM userWorkSheetVM)
        {
            //确定待检测试管架数量
            int shelfCount = 0;

            // 试管架列表
            for (int i = 0; i < userWorkSheetVM.TestTubeShelfList.Count; i++)
            {
                //if (!userWorkSheetVM.TestTubeShelfList[i].IsOrder)//判断是否已经排序
                //{

                // 某个试管样本架上的试管列表
                for (int j = 0; j < userWorkSheetVM.TestTubeShelfList[i].TestTubeInfoList.Count; j++)
                {

                    // 某个试管中的样本检查项列表
                    for (int k = 0; k < userWorkSheetVM.TestTubeShelfList[i].TestTubeInfoList[j].DetectItems.Count; k++)
                    {
                        ReactionCup cup = new ReactionCup();
                        cup.DetectItemModel = userWorkSheetVM.TestTubeShelfList[i].TestTubeInfoList[j].DetectItems[k];
                        cup.DetectItem = cup.DetectItemModel.detectItem;
                        cup.TestTubeShelfBarcode = userWorkSheetVM.TestTubeShelfList[i].barcode;
                        cup.TestTubeHoleNumber = (byte)userWorkSheetVM.TestTubeShelfList[i].TestTubeInfoList[j].holeNumber;
                        cup.SampleInfoID = userWorkSheetVM.TestTubeShelfList[i].TestTubeInfoList[j].SampleID;

                        //bool repeatCup = false; 
                        //foreach (ReactionCup lastCup in mCupList) //查看是否已做列表中已有
                        //{
                        //    if ((lastCup.SampleInfoID == cup.SampleInfoID) && (lastCup.DetectItem.Equals(cup.DetectItem)))
                        //    {
                        //        repeatCup = true;
                        //        break;
                        //    }
                        //}
                        //if (repeatCup == false)

                        mCupList.Add(cup);

                        //统计样本数量
                        string itemName = userWorkSheetVM.TestTubeShelfList[i].TestTubeInfoList[j].DetectItems[k].detectItem;
                        if (userWorkSheetVM.WorkItemList.ContainsKey(itemName))
                        {
                            userWorkSheetVM.WorkItemList[itemName].SampleCount++;
                        }
                        else
                        {
                            WorkSheetStatistics item = new WorkSheetStatistics();
                            item.DetectItem = itemName;
                            userWorkSheetVM.WorkItemList.Add(itemName, item);
                        }
                    }
                }
                userWorkSheetVM.TestTubeShelfList[i].IsOrder = true;
                shelfCount++;
            }
            //}
            ServiceProvider.Monitor.InShelfCount = shelfCount; //赋值试管架数量           

            //ReactionStripOrder();//分配杯条列表
            return mCupList;
        }

        /// <summary>
        /// 反应杯排序放入反应条
        /// </summary>
        /// <returns></returns>
        private void ReactionStripOrder()
        {
            var cupList = from cup in mCupList
                          where cup.IsInStrip == false
                          orderby cup.DetectItemModel.DetectionMethod, cup.SampleInfoID
                          select cup;
            int cupCount = 0;
            ReactionStrip strip = null;

            foreach (ReactionCup cup in cupList)
            {
                int cupOrder = cupCount % 4;
                if (cupOrder % 4 == 0)//一条4个杯子,
                {
                    strip = new ReactionStrip();
                    strip.ReactionCupList = new ObservableCollection<ReactionCup>();
                    mStripList.Add(strip);    // 不适用反应条进行实验
                    strip.ID = mStripList.Count;
                }
                cup.IsInStrip = true;
                strip.ReactionCupList.Add(cup);
                cup.ReactStripSeat = byte.Parse(cupOrder.ToString());
                cupCount++;
            }
        }

        #endregion // 根据用户设置，生成检查项列表

        #region 统计本次样本、试剂
        /// <summary>
        /// 统计试剂信息
        /// </summary>
        /// <param name="reagentKitVM"></param>
        public void StatisticsReagentKit(ReagentKitVM reagentKitVM)
        {
            reagentKitVM.ReagentItemList = new Dictionary<string, ReagentKitStatistics>();
            foreach (Model.ReagentKit kit in reagentKitVM.ReagentKitList)
            {

                if (kit.ReagentModel1 != null)
                {
                    if (reagentKitVM.ReagentItemList.ContainsKey(kit.ReagentModel1.DetectItem))
                    {
                        reagentKitVM.ReagentItemList[kit.ReagentModel1.DetectItem].RemainTimes1 += kit.RemainTimes1;
                    }
                    else
                    {
                        ReagentKitStatistics kitStatistics = new ReagentKitStatistics();
                        kitStatistics.ItemModel = kit.ReagentModel1.DetectItemModel;
                        kitStatistics.RemainTimes1 = kit.RemainTimes1;
                        reagentKitVM.ReagentItemList.Add(kit.ReagentModel1.DetectItem, kitStatistics);
                    }
                }
                //if(kit.ReagentModel2!=null)
                //{
                //    if (reagentKitVM.ReagentItemList.ContainsKey(kit.ReagentModel2.DetectItem))
                //    {
                //        if (reagentKitVM.ReagentItemList[kit.ReagentModel2.DetectItem].RemainTimes2==null)
                //        {
                //            reagentKitVM.ReagentItemList[kit.ReagentModel2.DetectItem].RemainTimes2 = kit.RemainTimes2;
                //        }
                //        else
                //        {
                //            reagentKitVM.ReagentItemList[kit.ReagentModel2.DetectItem].RemainTimes2 += kit.RemainTimes2;
                //        }
                //    }
                //    else
                //    {
                //        ReagentKitStatistics kitStatistics = new ReagentKitStatistics();
                //        kitStatistics.ItemModel = kit.ReagentModel2.DetectItemModel;
                //        kitStatistics.RemainTimes2 = kit.RemainTimes2;
                //        reagentKitVM.ReagentItemList.Add(kit.ReagentModel2.DetectItem, kitStatistics);
                //    }
                //}
            }
        }
        /// <summary>
        /// 检查试剂种类
        /// </summary>
        /// <param name="itemCount"></param>
        /// <param name="reagentCount"></param>
        public bool CheckReagent(Dictionary<string, WorkSheetStatistics> itemCount, Dictionary<string, ReagentKitStatistics> reagentCount)
        {
            bool res = true;
            foreach (WorkSheetStatistics item in itemCount.Values)
            {
                res = true;
                if (reagentCount.ContainsKey(item.DetectItem))
                {
                    //System.Windows.MessageBox.Show("试剂不全");
                    if (reagentCount[item.DetectItem].RemainTimes1 <= 0)
                    {
                        Console.WriteLine("试剂1不足" + item.DetectItem);
                        res = false;
                    }
                    if (reagentCount[item.DetectItem].RemainTimes2 <= 0)
                    {
                        Console.WriteLine("试剂2不足" + item.DetectItem);
                        res = false;
                    }

                }
                else
                {
                    Console.WriteLine("试剂不全" + item.DetectItem);
                    res = false;
                }
                if (!res)
                {
                    ServiceProvider.ReagentKitVM.NeedReagentItem.Add(item.DetectItem);
                }
            }

            return res;
        }
        #endregion

        #region // 排列样本及其检查项到反应条的反应杯中(不再使用）

        // 第一，建立一个检查项目列表；
        // 第二，将检查项列表分解为标准品列表、校准品列表、阴阳对照列表、质控品列表，紧急样本列表、普通样本列表
        // 第三，先将第一个标准品放在第一个反应条的第一个孔位上，并将其从标准品列表中去掉；
        // 第四，从标准品列表的第二个标准品开始，查找与条1孔1上的样本具有相同孵育时间和相同检测方法的样本，
        // 将其依次放在反应条其余孔中。凡是已排列在反应条中的标准品从标准品列表中删除。
        // 第五，从当前的标准品列表中取得第一个标准品，重复第三和第四项。
        // 第六，依次从其它种类的样本列表中，取出具有相同孵育时间与相同检测方法的样本，
        // 按照第三、四、五的方法将它们加入到工作列表中。

        /// <summary>
        /// 排列样本及其检查项到反应条的反应杯中
        /// </summary>
        public void ArrangeReactionStripsAndCups()
        {
            // 如果没有检查项列表，则返回
            if (mUserSettedDetectItemList.Count == 0)
                return;

            byte cupNo = 0;                     // 当前杯编号
            int sortedItemCount = 0;            // 已排列过的检查项数量
            int hatchTime = 0;                  // 孵育时间
            ReactionStrip strip = null;         // 反应条
            ObservableCollection<ReactionCup> cupList = null;      // 反应杯列表

            // 条件：已排列过的检查项数量小于用户总共设置的检查项数量
            while (sortedItemCount < mUserSettedDetectItemList.Count)
            {
                cupNo = 1;          // 将杯位号初始化为1
                hatchTime = 0;      // 将孵育时间初始化为0                

                // 循环查找未排列过的检查项
                for (int i = 0; i < mUserSettedDetectItemList.Count; i++)
                {
                    // 如果检查项没有被排列过，则从数据库查找此项的详细信息
                    if (mUserSettedDetectItemList[i].ItemLocation == "")
                    {
                        // 根据检查项目的名称，从检查项表中取出相关信息
                        Clipper.Model.DetectItems items = new Model.DetectItems();
                        BLL.DetectItems bllItems = new DetectItems();
                        items = bllItems.GetModel(mUserSettedDetectItemList[i].DetectItemName);

                        // 如果反应杯的编号为1，则创建反应条和反应杯列表
                        if (cupNo == 1)
                        {
                            // 创建一个反应条和一个反应杯列表
                            strip = new ReactionStrip();
                            strip.ID = ServiceProvider.gReactionStripList.Count + 1;
                            cupList = new ObservableCollection<ReactionCup>();
                        }

                        // 如果杯位号为1且孵育时间为0，则说明此检查项是未被排列过的所有项中的第一项，
                        // 将它直接放在当前反应条的第一个反应杯中
                        if (hatchTime == 0)
                        {
                            ReactionCup cup = new ReactionCup();
                            cup.DetectItem = mUserSettedDetectItemList[i].DetectItemName;
                            cup.DetectItemModel = items;
                            cup.ReactStripSeat = cupNo;
                            cup.SampleInfoID = mUserSettedDetectItemList[i].SampleID;
                            cup.TestTubeShelfBarcode = mUserSettedDetectItemList[i].TubeShelfID;
                            cup.TestTubeHoleNumber = mUserSettedDetectItemList[i].HoleSite;
                            cup.Note = strip.ID.ToString();
                            cupList.Add(cup);
                            mUserSettedDetectItemList[i].ItemLocation = strip.ID.ToString() +
                                                                        "," + cup.ReactStripSeat.ToString();
                            cupNo++;
                            hatchTime = items.incubationTime;
                            sortedItemCount++;
                        }
                        else  // 如果不是未排列过的第一个检查项
                        {
                            // 如果当前检查项的孵育时间与当前反应条第一个反应杯的孵育时间相同，则将其放在当前杯位
                            if (items.incubationTime == hatchTime)
                            {
                                ReactionCup cup = new ReactionCup();
                                cup.DetectItem = mUserSettedDetectItemList[i].DetectItemName;
                                cup.DetectItemModel = items;
                                cup.ReactStripSeat = cupNo;
                                cup.SampleInfoID = mUserSettedDetectItemList[i].SampleID;
                                cup.TestTubeShelfBarcode = mUserSettedDetectItemList[i].TubeShelfID;
                                cup.TestTubeHoleNumber = mUserSettedDetectItemList[i].HoleSite;
                                cup.Note = strip.ID.ToString();
                                cupList.Add(cup);
                                mUserSettedDetectItemList[i].ItemLocation = strip.ID.ToString() +
                                                                            "," + cup.ReactStripSeat.ToString();
                                cupNo++;
                                sortedItemCount++;

                                // 如果反应杯的位号大于8，则说明当前反应条已排满，
                                // 将反应杯列表加到当前反应条中，将当前反应条加入反应条列表中，当前杯位号设置为1
                                if (cupNo > 8)
                                {
                                    strip.ReactionCupList = cupList;
                                    ServiceProvider.gReactionStripList.Add(strip);
                                    cupNo = 1;
                                }
                            }
                        }
                    }
                }
                strip.ReactionCupList = cupList;
                ServiceProvider.gReactionStripList.Add(strip);
            }
        }


        #endregion // 排列样本及其检查项到反应条的反应杯中
    }
}
